import { EnumBetResult, EnumBjlResult } from "@/models/enums/EnumBjlResult";
import { ExcutePlan, RecmInfo, RoundInfo } from "../ExecutePlan";
import { FixedStrategy } from "../recmStrategy/FixedStrategy";
import { IMoneyStrategy } from "../IMoneyStrategy";
import { IPlan } from "../IExecutePlan";
import { WisdomGroupMoneyStrategyV2 } from "./WisdomMoneyStrategyV2";
import { NormalStepMoneyStrategy } from "./NormalStepMoneyStrategy";
import { BossRabbitMoneyStrategy, BossRabbitToStepMoneyStrategy, BossThreeRabiatMoneyStrategy } from "./BossRabitMoneyStrategy";
import { WisdomMoneyStrategyV29Group4 } from "./WisdomMoneyStrategyV29Group4";
import { StepMultipleMoneyStrategy } from "./StepMultipleMoneyStrategy";


export class WisdomMoneyStrategyV29Group4V5 extends WisdomMoneyStrategyV29Group4 implements IMoneyStrategy {
    subPlan: IPlan[] = [];
    debugCompoenent: string = "WisdomMoneyStrategyV2Debug";
    strategyName: string;
    startIndex: number = -1;
    startLevel: number = 10000;
    bgroupCount: number = 1;
    oneReturnMoney: number = 640;
    twoReturnMoney: number = 640;
    protected _subPlanSum: number = 0;
    public get subPlanSum() {
        return this._subPlanSum;
    }
    protected _rabbitPlanSum: number = 0;
    public get rabbitPlanSum() {
        return this._rabbitPlanSum;
    }
    constructor(name?: string) {
        super(name);
        this.strategyName = name ?? "GroupMoneyStrategy" + (new Date()).getMilliseconds() + parseInt((Math.random() * 1000).toString());
        this.subPlan = [];
        this.resetStrategy();
    }
    showMoney(): [EnumBjlResult, number] {
        let zm = 0;
        let xm = 0;
        let recmV = EnumBjlResult.U;
        let recmMoney = 0;
        let sum = 0;

        this.subPlan.forEach(pl => {
            let [rv, rm] = pl.showMoney();
            pl.recmInfo.recmV = rv;
            pl.recmInfo.recmMoney = rm;

            if (pl.recmInfo.recmV == EnumBjlResult.Z) {
                zm += (pl.recmInfo.recmMoney * pl.multiple);

            }
            else if (pl.recmInfo.recmV == EnumBjlResult.X) {
                xm += (pl.recmInfo.recmMoney * pl.multiple);
            }
        });
        if (zm > xm) {
            recmV = EnumBjlResult.Z;
            recmMoney = zm - xm;
        }
        else if (xm > zm) {
            recmV = EnumBjlResult.X;
            recmMoney = xm - zm;
        }
        else {
            recmV = EnumBjlResult.U;
        }


        return [recmV, recmMoney];
    }
    resetRecm() {
        this.subPlan.forEach(item => item.resetRecm());
    }
    resetStrategy(): void {
        this.subPlan.splice(0, this.subPlan.length);
        let tz1 = new ExcutePlan();
        tz1.multiple = 2;
        tz1.planName = "兔正1";
        tz1.recmStrategy = [new FixedStrategy({ reverse: false })];
        tz1.moneyStrategy = [new BossRabbitMoneyStrategy("兔正1", {
            baseMoney: 10,
            winStep: 1,
            failStep: -2,
            currentMoney: 10,
            prevMoney: 0,
            prevPrevMoney: 0,
            maxMoney: 9999999999
        })];
        tz1.toResult(new RoundInfo());
        this.subPlan.push(tz1);

        let tf1 = new ExcutePlan();
        tf1.planName = "兔反1";
        tf1.multiple = 2;
        tf1.recmStrategy = [new FixedStrategy({ reverse: true })];
        tf1.moneyStrategy = [new BossRabbitMoneyStrategy("兔反1", {
            baseMoney: 10,
            winStep: 1,
            failStep: -2,
            currentMoney: 10,
            prevMoney: 0,
            prevPrevMoney: 0,
            maxMoney: 9999999999
        })];
        tf1.toResult(new RoundInfo());
        this.subPlan.push(tf1);

        let tz2 = new ExcutePlan();
        tz2.planName = "兔正2";
        tz2.multiple = 1;
        tz2.recmStrategy = [new FixedStrategy({ reverse: false })];
        tz2.moneyStrategy = [new BossRabbitToStepMoneyStrategy("兔正2", {
            baseMoney: 10,
            rabbitWinStep: -2,
            rabbitFailStep: 1,
            prevMoney: 10,
            currentMoney: 10,
            changeMoney: 9999999999,
            winStepMoney: -100,
            failStepMoney: 100,
        })];
        tz2.toResult(new RoundInfo());
        this.subPlan.push(tz2);

        let tf2 = new ExcutePlan();
        tf2.planName = "兔反2";
        tf2.multiple = 1;
        tf2.recmStrategy = [new FixedStrategy({ reverse: true })];
        tf2.moneyStrategy = [new BossRabbitToStepMoneyStrategy("兔反2", {
            baseMoney: 10,
            rabbitWinStep: -2,
            rabbitFailStep: 1,
            prevMoney: 10,
            currentMoney: 10,
            changeMoney: 9999999999,
            winStepMoney: -100,
            failStepMoney: 100,
        })];
        tf2.toResult(new RoundInfo());
        this.subPlan.push(tf2);

        let zb = new ExcutePlan();
        zb.planName = "正倍";
        zb.multiple = 1;
        zb.recmStrategy = [new FixedStrategy({ reverse: false })];
        zb.moneyStrategy = [new StepMultipleMoneyStrategy("正倍", {
            multiple: 2,
            baseMoney: 10,
            stepLimitMoney: 999999,
            stepMoney: 50
        })];
        zb.toResult(new RoundInfo());
        this.subPlan.push(zb);

        let fb = new ExcutePlan();
        fb.planName = "反倍";
        fb.multiple = 1;
        fb.recmStrategy = [new FixedStrategy({ reverse: true })];
        fb.moneyStrategy = [new StepMultipleMoneyStrategy("反倍", {
            multiple: 2,
            baseMoney: 10,
            stepLimitMoney: 999999,
            stepMoney: 50
        })];
        fb.toResult(new RoundInfo());
        this.subPlan.push(fb);

        let zb1 = new ExcutePlan();
        zb1.planName = "正倍1";
        zb1.multiple = 1;
        zb1.running = false;
        zb1.recmStrategy = [new FixedStrategy({ reverse: false })];
        zb1.moneyStrategy = [new StepMultipleMoneyStrategy("正倍1", {
            multiple: 2,
            baseMoney: 10,
            stepLimitMoney: 999999,
            stepMoney: 50
        })];
        this.subPlan.push(zb1);

        let fb1 = new ExcutePlan();
        fb1.planName = "反倍1";
        fb1.multiple = 1;
        fb1.running = false;
        fb1.recmStrategy = [new FixedStrategy({ reverse: true })];
        fb1.moneyStrategy = [new StepMultipleMoneyStrategy("反倍1", {
            multiple: 2,
            baseMoney: 10,
            stepLimitMoney: 999999,
            stepMoney: 50
        })];
        this.subPlan.push(fb1);

        this.bgroupCount = 1;
        //this.returnMoney = 640;
        this.oneReturnMoney = 640;
        this.twoReturnMoney = 640;

    }
    setSubResult(pl: ExcutePlan, roundInfo: RoundInfo) {
        pl.setResult(roundInfo, pl.recmInfo, pl.multiple, pl.waterRate, pl.fuliRate);

        let m = pl.recmInfo.summaryInfo.winMoney - pl.recmInfo.summaryInfo.failMoney;
        this._subPlanSum += m;

        let userRecmV = pl.toResult(roundInfo);
        let newRoundInfo: RoundInfo = Object.assign({}, roundInfo, { userRecm: userRecmV });
        pl.userRecmInfo.recmV = userRecmV;
        return newRoundInfo;
    }
    setRabbitSum(pl: ExcutePlan) {
        if (pl.recmInfo.recmV == EnumBjlResult.Z) {
            this._rabbitPlanSum += (pl.recmInfo.recmMoney * pl.multiple);
        }
        else if (pl.recmInfo.recmV == EnumBjlResult.X) {
            this._rabbitPlanSum -= (pl.recmInfo.recmMoney * pl.multiple);
        }
    }
    toSubMoney(pl: ExcutePlan, roundInfo: RoundInfo) {
        if (pl.running) {
            let [rv, rm] = pl.toMoney(roundInfo, pl.recmInfo, pl.userRecmInfo, pl.baseMoney);
            pl.recmInfo.preBetCount = pl.recmInfo.betCount;
            pl.recmInfo.recmV = rv;
            pl.recmInfo.recmMoney = rm;
            if (rv != EnumBjlResult.U) {
                //pl.recmInfo.
                pl.recmInfo.betCount++;
            }
        }
        else {
            pl.recmInfo.recmV = EnumBjlResult.U;
            pl.recmInfo.recmMoney = 0;
        }

    }

    toMoney(roundInfo: RoundInfo, recmInfo: RecmInfo, userRecm: RecmInfo, baseMoney: number): [EnumBjlResult, number] {
        let zm = 0;
        let xm = 0;
        let recmV = EnumBjlResult.U;
        let recmMoney = 0;
        let sumWin = 0;

        let prevRabbitRecmMoney = this._rabbitPlanSum;
        let rabbitRecm = EnumBjlResult.U;
        let rabbitRecmResult = EnumBetResult.NotBet;
        if (this._rabbitPlanSum > 0) {
            rabbitRecm = EnumBjlResult.Z;
        }
        else if (this._rabbitPlanSum < 0) {
            rabbitRecm = EnumBjlResult.X;
        }
        if (rabbitRecm != EnumBjlResult.U) {
            rabbitRecmResult = roundInfo.currentResult == rabbitRecm ? EnumBetResult.Success : EnumBetResult.Fail;
        }



        let reset = false;
        this._subPlanSum = sumWin;

        let tz1 = this.subPlan[0];
        let tf1 = this.subPlan[1];
        let tz2 = this.subPlan[2];
        let tf2 = this.subPlan[3];

        let zb = this.subPlan[4];
        let fb = this.subPlan[5];
        let zb1 = this.subPlan[6];
        let fb1 = this.subPlan[7];

        let tz2RoundInfo = this.setSubResult(tz2, roundInfo);

        let tf2RoundInfo = this.setSubResult(tf2, roundInfo);

        let tz1MoneyStrategy = tz1.moneyStrategy[0] as BossRabbitMoneyStrategy;
        let tf1MoneyStrategy = tf1.moneyStrategy[0] as BossRabbitMoneyStrategy;
        let tz2MoneyStrategy = tz2.moneyStrategy[0] as BossRabbitToStepMoneyStrategy;
        let tf2MoneyStrategy = tf2.moneyStrategy[0] as BossRabbitToStepMoneyStrategy;


        this.toSubMoney(tz2, tz2RoundInfo);
        this.toSubMoney(tf2, tf2RoundInfo);
        let tf1RoundInfo = this.setSubResult(tf1, roundInfo);

        this.toSubMoney(tf1, tf1RoundInfo);

        let tz1RoundInfo = this.setSubResult(tz1, roundInfo);
        this.toSubMoney(tz1, tz1RoundInfo);

        // let zbRoundInfo = this.setSubResult(zb, roundInfo);
        // this.toSubMoney(zb, zbRoundInfo);

        // let fbRoundInfo = this.setSubResult(fb, roundInfo);
        // this.toSubMoney(fb, fbRoundInfo);
        ///////////////////////////////////////////////////////////////////////////

        this._rabbitPlanSum = 0;
        this.setRabbitSum(tz1);
        this.setRabbitSum(tf1);
        this.setRabbitSum(tz2);
        this.setRabbitSum(tf2);

        ///////////////////////////////////////////////////////////////////////////
        if (zb.running) {
            let zbRoundInfo = this.setSubResult(zb, roundInfo);
            this.toSubMoney(zb, zbRoundInfo);
        }

        if (fb.running) {
            let fbRoundInfo = this.setSubResult(fb, roundInfo);
            this.toSubMoney(fb, fbRoundInfo);
        }

        ///////////////////////////////////////////////////////////////////////////
        if (zb1.running) {
            let zb1RoundInfo = this.setSubResult(zb1, roundInfo);
            this.toSubMoney(zb1, zb1RoundInfo);
        }

        if (fb1.running) {
            let fb1RoundInfo = this.setSubResult(fb1, roundInfo);
            this.toSubMoney(fb1, fb1RoundInfo);
        }
        ///////////////////////////////////////////////////////////////////////////
        let zfbRecm = Math.abs(zb.recmInfo.recmMoney) > Math.abs(fb.recmInfo.recmMoney)
            ? zb
            : fb;
        let zfRecmMoney = zfbRecm.recmInfo.recmMoney;

        let zfb1Recm = Math.abs(zb1.recmInfo.recmMoney) > Math.abs(fb1.recmInfo.recmMoney)
            ? zb1
            : fb1;
        let zf1RecmMoney = zfb1Recm.recmInfo.recmMoney;

        ///////////////////////////////////////////////////////////////////////////
        if ((Math.abs(zb.recmInfo.recmMoney) >= 640
            || Math.abs(fb.recmInfo.recmMoney) >= 640)
            && Math.abs(this._rabbitPlanSum) < Math.abs(zfRecmMoney)
            && (zb.running || fb.running)
        ) {

            if (zfbRecm.recmInfo.recmV == EnumBjlResult.Z) {
                this.oneReturnMoney = zfbRecm.recmInfo.recmMoney;
            }
            else if (zfbRecm.recmInfo.recmV == EnumBjlResult.X) {
                this.oneReturnMoney = -zfbRecm.recmInfo.recmMoney;
            }

            zb.running = false;
            fb.running = false;
            zb.recmInfo.recmV = EnumBjlResult.U;
            fb.recmInfo.recmV = EnumBjlResult.U;

            zb1.running = true;
            fb1.running = true;

            ///////////////////////////////////////////////////////////////////////////
            let zb1RoundInfo = this.setSubResult(zb1, roundInfo);
            this.toSubMoney(zb1, zb1RoundInfo);
            let fb1RoundInfo = this.setSubResult(fb1, roundInfo);
            this.toSubMoney(fb1, fb1RoundInfo);
        }
        else {
            let zfbv = 0;
            if (zfbRecm.recmInfo.recmV == EnumBjlResult.Z) {
                zfbv = zfbRecm.recmInfo.recmMoney;
            }
            else if (zfbRecm.recmInfo.recmV == EnumBjlResult.X) {
                zfbv = -zfbRecm.recmInfo.recmMoney;
            }
            this.oneReturnMoney = Math.abs(zfbv) > Math.abs(this.oneReturnMoney) ? zfbv : this.oneReturnMoney;
        }
        if ((Math.abs(zb1.recmInfo.recmMoney) >= 640
            || Math.abs(fb1.recmInfo.recmMoney) >= 640)
            && Math.abs(this._rabbitPlanSum) < Math.abs(zf1RecmMoney)
            && (zb1.running || fb1.running)
        ) {

            if (zfb1Recm.recmInfo.recmV == EnumBjlResult.Z) {
                this.twoReturnMoney = zfb1Recm.recmInfo.recmMoney;
            }
            else if (zfb1Recm.recmInfo.recmV == EnumBjlResult.X) {
                this.twoReturnMoney = -zfb1Recm.recmInfo.recmMoney;
            }

            zb1.running = false;
            fb1.running = false;
            zb1.recmInfo.recmV = EnumBjlResult.U;
            fb1.recmInfo.recmV = EnumBjlResult.U;
        }
        else {
            let zfbv = 0;
            if (zfb1Recm.recmInfo.recmV == EnumBjlResult.Z) {
                zfbv = zfb1Recm.recmInfo.recmMoney;
            }
            else if (zfb1Recm.recmInfo.recmV == EnumBjlResult.X) {
                zfbv = -zfb1Recm.recmInfo.recmMoney;
            }
            this.twoReturnMoney = Math.abs(zfbv) > Math.abs(this.twoReturnMoney) ? zfbv : this.twoReturnMoney;
        }

        if (
            ((this.oneReturnMoney < 0 && this._rabbitPlanSum >= (-this.oneReturnMoney))
                || (this.oneReturnMoney > 0 && (-this._rabbitPlanSum) >= this.oneReturnMoney))
            && (!zb.running || !fb.running)) {
            // zb1.resetPlan();
            // fb1.resetPlan();
            zb1.running = false;
            fb1.running = false;
            zb1.recmInfo.recmV = EnumBjlResult.U;
            fb1.recmInfo.recmV = EnumBjlResult.U;

            zb.running = true;
            fb.running = true;

            let zbRoundInfo = this.setSubResult(zb, roundInfo);
            this.toSubMoney(zb, zbRoundInfo);

            let fbRoundInfo = this.setSubResult(fb, roundInfo);
            this.toSubMoney(fb, fbRoundInfo);
        }
        if (
            ((this.twoReturnMoney < 0 && this._rabbitPlanSum >= (-this.twoReturnMoney))
                || (this.twoReturnMoney > 0 && (-this._rabbitPlanSum) >= this.twoReturnMoney))
            && (!zb1.running && !fb1.running && !zb.running && !fb.running)) {

            zb1.running = true;
            fb1.running = true;

            ///////////////////////////////////////////////////////////////////////////
            let zb1RoundInfo = this.setSubResult(zb1, roundInfo);
            this.toSubMoney(zb1, zb1RoundInfo);
            let fb1RoundInfo = this.setSubResult(fb1, roundInfo);
            this.toSubMoney(fb1, fb1RoundInfo);

        }
        /////////////////////////////////////////////////////////////////////////
        this.subPlan.forEach(pl => {
            if (pl.running) {
                if (pl.recmInfo.recmV == EnumBjlResult.Z) {
                    zm += (pl.recmInfo.recmMoney * pl.multiple);

                }
                else if (pl.recmInfo.recmV == EnumBjlResult.X) {
                    xm += (pl.recmInfo.recmMoney * pl.multiple);
                }
            }

        })

        if (zm > xm) {
            recmV = EnumBjlResult.Z;
            recmMoney = zm - xm;
        }
        else if (xm > zm) {
            recmV = EnumBjlResult.X;
            recmMoney = xm - zm;
        }
        else {
            recmV = EnumBjlResult.U;
        }
        return [recmV, recmMoney];
    }

    copyValue(valueObj: any): void {
        var obj = valueObj as WisdomMoneyStrategyV29Group4V5;
        if (obj) {
            this.debugCompoenent = obj.debugCompoenent;
            this.startIndex = obj.startIndex;
            this._subPlanSum = obj._subPlanSum;
            this.bgroupCount = obj.bgroupCount;
            this._rabbitPlanSum = obj._rabbitPlanSum;
            this.oneReturnMoney = obj.oneReturnMoney;
            this.twoReturnMoney = obj.twoReturnMoney;

            for (let i = 0; i < this.subPlan.length; i++) {
                this.subPlan[i].copyValue(obj.subPlan[i]);
            }

        }
    }
}